# coding:utf-8
from django.db import transaction
from django.db.models import Sum
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from MSB_ERP.utils.get_inventory import get_inventory
from financial_info.models import ReceiptItemModel
from warehouse_info.models import PurchaseStorageModel, PurchaseStorageItemModel,SaleDeliverModel,SaleDeliverItemModel

class DeliveryItemSerializer(serializers.ModelSerializer):
    """
    出库单的 项目，序列化
    """
    # 注意：既然只有 库存数据没有，那么可以增加一个属性
    cur_inventory = serializers.SerializerMethodField(read_only=True, label='在当前仓库中库存')

    class Meta:
        model = SaleDeliverItemModel
        fields = '__all__'

    def get_cur_inventory(self, obj):  # 当前的obj为：SaleDeliverItemModel
        result = get_inventory(obj.goods.id, obj.warehouse.id)
        return result if result else 0


class DeliverySerializer(serializers.ModelSerializer):
    """
    出库单——反序列化器（用于新增和修改） 和 查询列表的序列化器（用于出库单列表）
    """
    item_list = DeliveryItemSerializer(many=True)
    # 出库单列表中需要展示：商品信息。
    goods_info = serializers.SerializerMethodField(read_only=True, label='列表中展示的商品信息')

    # 查询当前销售 出库单中已经 收金额
    already_receipt = serializers.SerializerMethodField(read_only=True, help_text='已经收款的金额')

    class Meta:
        model = SaleDeliverModel
        fields = '__all__'

    def get_already_receipt(self, obj: SaleDeliverModel):
        """
        查询当前 销售出库单中已经 收的货款金额
        :param obj: SaleDeliverModel
        :return: 0获取其他的数值
        """
        sum_dict = ReceiptItemModel.objects.filter(deliver_storage_id=obj.id)\
            .exclude(receipt__status='0')\
            .aggregate(sum=Sum('this_money'))
        if sum_dict:
            return sum_dict['sum'] if sum_dict['sum'] else 0
        return 0



    def get_goods_info(self, obj):
        """
        商品信息是由： 商品1名称 商品1规格 , 商品2名称 商品2规格 ，....
        """
        if obj.item_list.all():
            result = []
            for item in obj.item_list.all():
                result.append(item.name + (item.specification if item.specification else ''))
            return ', '.join(result)
        return ""

    # 同时插出出库单和 出库单中货品项。必须重写create
    def create(self, validated_data):
        item_list = validated_data.pop('item_list')
        with transaction.atomic():
            sd = SaleDeliverModel.objects.create(**validated_data)
            for item in item_list:
                psi = SaleDeliverItemModel.objects.create(sale_deliver=sd, **item)
                # 把一些冗余属性也加进去
                goods = item.get('goods')
                psi.specification = goods.specification
                psi.model_number = goods.model_number
                psi.number_code = goods.number_code
                psi.color = goods.color
                psi.category = goods.category
                psi.category_name = goods.category.name
                psi.units = goods.units
                psi.units_name = goods.units.basic_name
                psi.save()
        return sd

    # 同时插出出库单和出库单中货品项。必须重写update
    def update(self, instance, validated_data):
        if instance.status == '1':
            raise ValidationError("出库单已经生效，不能修改")
        item_list = validated_data.pop('item_list')
        old_list = instance.item_list.all()
        with transaction.atomic():
            if old_list.exists():
                # 然后把旧数据删除，因为在validated_data拿不到货品库存数据的ID
                instance.item_list.all().delete()

            for item in item_list:  # 重新插出出库项 数据
                psi = SaleDeliverItemModel.objects.create(sale_deliver=instance, **item)
                # 把一些冗余属性也加进去
                goods = item.get('goods')
                psi.specification = goods.specification
                psi.model_number = goods.model_number
                psi.number_code = goods.number_code
                psi.color = goods.color
                psi.category = goods.category
                psi.category_name = goods.category.name
                psi.units = goods.units
                psi.units_name = goods.units.basic_name
                psi.save()
            result = super(DeliverySerializer, self).update(instance=instance, validated_data=validated_data)
        return result





